﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Collections;
using G.Navigate;
using System.Linq;

namespace G.Controls
{
    public class GListBox : ListBox
    {
        public static readonly DependencyProperty LoadingForegroundProperty = DependencyProperty.Register("LoadingForeground", typeof(Brush), typeof(GListBox), null);

        public Brush LoadingForeground
        {
            get
            {
                return this.GetValue(LoadingForegroundProperty) as Brush;
            }
            set
            {
                this.SetValue(LoadingForegroundProperty, value);
            }
        }

        public static readonly DependencyProperty NoMsgNotifyProperty = DependencyProperty.Register("NoMsgNotify", typeof(string), typeof(GListBox), null);

        public string NoMsgNotify
        {
            get
            {
                return this.GetValue(NoMsgNotifyProperty) as string;
            }
            set
            {
                this.SetValue(NoMsgNotifyProperty, value);
            }
        }

        /// <summary>
        /// 只读属性，如果想清空数据源，使用ClearItems方法，如果添加数据使用LoadData泛型方法
        /// </summary>
        public new IEnumerable ItemsSource
        {
            get
            {
                return base.ItemsSource;
            }
            set
            {
                base.ItemsSource = value;
            }
        }
        public static readonly DependencyProperty LoadingIndicatorVisibleProperty = DependencyProperty.Register("LoadingIndicatorVisible", typeof(Visibility), typeof(GListBox), new PropertyMetadata(Visibility.Collapsed));
        public Visibility LoadingIndicatorVisible
        {
            get
            {
                return (Visibility)this.GetValue(LoadingIndicatorVisibleProperty);
            }
            set
            {
                this.SetValue(LoadingIndicatorVisibleProperty, value);
            }
        }

        private string DataKey;
        public GListBox()
            : base()
        {
            this.DefaultStyleKey = typeof(GListBox);
            this.Loaded += new RoutedEventHandler(GListBox_Loaded);
            PropertyValueChangedNotify.Create("ItemsSource", this).PropertyValueChanged += new PropertyValueChangedHandle(GListBox_PropertyValueChanged);
        }

        void GListBox_Loaded(object sender, RoutedEventArgs e)
        {
            if (DataItem != null)
            {
                this.ScrollIntoView(DataItem);
                DataItem = null;
            }
        }
        ProgressBar loadingIndicator;
        TextBlock txtNoResult;
        protected ScrollViewer ScrollViewer { get; private set; }
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            ScrollViewer = this.GetTemplateChild("ScrollViewer") as ScrollViewer;
            txtNoResult = this.GetTemplateChild("txtNoResult") as TextBlock;
            loadingIndicator = this.GetTemplateChild("loadingIndicator") as ProgressBar;
        }


        /// <summary>
        /// 开始加载数据，主要是为了显示加载动画
        /// </summary>
        public void BeginLoadingData()
        {
            LoadingData();
        }
        protected virtual void LoadingData()
        {
            //this.OwnerPage.RegisterLoading(null);
            //if (loadingIndicator != null)
            //{
            //    loadingIndicator.IsIndeterminate = true;
            //}
            LoadingIndicatorVisible = System.Windows.Visibility.Visible;
        }

        protected GBasePage OwnerPage { get; private set; }
        /// <summary>
        /// 启用墓碑ListBox
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="page"></param>
        public virtual void EnableTombstoneListBox<T>(GBasePage page)
        {
            if (this.Name == string.Empty)
            {
                throw new ArgumentNullException("Listbox的名称不能为空");
            }

            if (this.ItemsSource == null)
            {
                this.DataKey = this.Name + "_Data";//存放数据的键
                this.OwnerPage = page;
                //this.OwnerPage.NavigatingFrom -= OwnerPage_NavigatingFrom;
                //this.OwnerPage.NavigatingFrom += OwnerPage_NavigatingFrom;
                if (this.OwnerPage.CanUseState && OwnerPage.State.ContainsKey(this.DataKey))
                {
                    var data = OwnerPage.State[this.DataKey] as ObservableCollection<T>;
                    LoadData<T>(data);
                    //if (this.OwnerPage.State.ContainsKey(this.Name + "_ScreenData"))
                    //{
                    //    ObservableCollection<T> itemsSource = this.GetItemsSource<T>();
                    //    int item = (int)this.OwnerPage.State[this.Name + "_ScreenData"];
                    //    DataItem = itemsSource[item];
                    //    System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();
                    //    timer.Interval = TimeSpan.FromSeconds(1);
                    //    timer.Tick += (e, s) =>
                    //    {
                    //        this.ScrollIntoView(DataItem);
                    //        DataItem = null;
                    //        this.OwnerPage.State.Remove(this.Name + "_ScreenData");
                    //        timer.Stop();
                    //    };
                    //    timer.Start();
                    //}
                }
            }

        }

        //void OwnerPage_NavigatingFrom(object sender, System.Windows.Navigation.NavigatingCancelEventArgs e)
        //{
        //    if (e.NavigationMode == System.Windows.Navigation.NavigationMode.New)
        //    {
        //        var items = VisualTreeHelper.FindElementsInHostCoordinates(new Rect(0, 0, this.ActualWidth, 200), this);
        //        if (this.OwnerPage.State.ContainsKey(this.Name + "_ScreenData"))
        //        {
        //            this.OwnerPage.State.Remove(this.Name + "_ScreenData");
        //        }
        //        foreach (var item in items)
        //        {
        //            if (item is ListBoxItem)
        //            {
        //                var data = (item as ListBoxItem).DataContext;
        //                int a = 0;
        //                foreach (var aa in this.ItemsSource)
        //                {
        //                    if (aa == data)
        //                    {
        //                        this.OwnerPage.State[this.Name + "_ScreenData"] = a;
        //                        break;
        //                    }
        //                    a++;
        //                }
        //                break;
        //            }
        //        }
        //    }
        //}

        protected override DependencyObject GetContainerForItemOverride()
        {
            return base.GetContainerForItemOverride();
        }
        protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
        {
            base.PrepareContainerForItemOverride(element, item);
        }

        /// <summary>
        /// 清空集合内容
        /// </summary>
        public virtual void ClearItems()
        {
            this.ScrollIntoView(this.Items.FirstOrDefault());
            this.ItemsSource = null;
            if (this.DataKey != null && this.OwnerPage.CanUseState && this.OwnerPage.State.ContainsKey(this.DataKey))
            {
                this.OwnerPage.State.Remove(this.DataKey);
            }
        }
        /// <summary>
        /// 移除项
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="objs"></param>
        public void RemoveItem<T>(params T[] objs)
        {
            ObservableCollection<T> itemsSource = GetItemsSource<T>();
            foreach (var item in objs)
            {
                itemsSource.Remove(item);
            }
        }


        public void InsertOf<T>(T obj, int index)
        {
            ObservableCollection<T> itemsSource = GetItemsSource<T>();
            itemsSource.Insert(index, obj);
        }
        /// <summary>
        /// 获取ListBox的ItemsSource
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public ObservableCollection<T> GetItemsSource<T>()
        {
            return this.ItemsSource as ObservableCollection<T>;
        }

        object DataItem = null;
        private bool IsObservableCollection;
        public virtual void LoadData<T>(IEnumerable<T> datas)
        {
            //if (!this.OwnerPage.CanUseState)
            //    return;
            if (datas == null)
            {
                datas = new List<T>();
            }
            ObservableCollection<T> itemsSource = GetItemsSource<T>();
            if (itemsSource == null)
            {
                itemsSource = new ObservableCollection<T>();
                IsObservableCollection = true;
                this.ItemsSource = itemsSource;
            }
            itemsSource.CollectionChanged -= itemsSource_CollectionChanged;
            foreach (var item in datas)
            {
                itemsSource.Add(item);
            }
            //if (loadingIndicator != null)
            //{
            //    //loadingIndicator.StopAnimation();
            //    loadingIndicator.IsIndeterminate = false;
            //}
            //this.OwnerPage.UnregisterLoading();
            itemsSource.CollectionChanged += itemsSource_CollectionChanged;
            SetResultVisible();
            LoadingIndicatorVisible = System.Windows.Visibility.Collapsed;
        }

        void itemsSource_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            SetResultVisible();
        }

        private void SetResultVisible()
        {
            //去报每次修改集合内容后都能及时存储
            if (this.OwnerPage.CanUseState)
            {
                this.OwnerPage.State[this.DataKey] = this.ItemsSource;
            }
            if (txtNoResult != null)
            {
                if (this.Items.Count > 0)
                {
                    txtNoResult.Visibility = System.Windows.Visibility.Collapsed;
                }
                else
                {
                    txtNoResult.Visibility = System.Windows.Visibility.Visible;
                }
            }
        }
        void GListBox_PropertyValueChanged(DependencyObject d, PropertyValueChangedEventArgs e)
        {
            if (!IsObservableCollection)
            {
                throw new Exception("不能给数据源直接赋值,如果想要给数据源赋值请调用LoadedData方法");
            }
            if (this.OwnerPage == null)
            {
                throw new Exception("在没有启用墓碑机制前无法给ListBox赋值");
            }
            if (this.OwnerPage.CanUseState)
            {
                this.OwnerPage.State[this.DataKey] = this.ItemsSource;
            }
            //else
            //{
            //    throw new Exception("无法在导航的时候使用state");
            //}
        }
    }
}
